Sparse atlases¶

This demo showcases the INIA19 template and atlas for the rhesus monkey. The INIA19 atlas is sparse, containing hundreds of regions distributed across thousands of indices. NiiVue efficiently visualizes this type of atlas using minimal resources, ensuring smooth interactivity even on low-power devices.

This Python script is similar the corresponding JavaScript web demo

In [1]:
from pathlib import Path

from ipyniivue import download_dataset

BASE_API_URL = "https://niivue.com/demos/images/"
DATA_FOLDER = Path("images")

# Download data for example
download_dataset(
    BASE_API_URL,
    dest_folder=DATA_FOLDER,
    files=[
        "inia19-t1-brain.nii.gz",
        "inia19-NeuroMaps.nii.gz",
        "inia19-NeuroMaps.json",
    ],
)
inia19-t1-brain.nii.gz already exists.
inia19-NeuroMaps.nii.gz already exists.
inia19-NeuroMaps.json already exists.
Dataset downloaded successfully to images.
In [2]:
import json

import ipywidgets as widgets
from IPython.display import display

from ipyniivue import DragMode, NiiVue, ShowRender

# Setup NiiVue Instance
nv = NiiVue(
    back_color=(0.5, 0.5, 0.5, 1),
    show_3d_crosshair=True,
    drag_mode=DragMode.PAN,
    yoke_3d_to_2d_zoom=True,
    multiplanar_show_render=ShowRender.ALWAYS,
)

nv.load_volumes(
    [
        {"path": DATA_FOLDER / "inia19-t1-brain.nii.gz"},
        {"path": DATA_FOLDER / "inia19-NeuroMaps.nii.gz", "opacity": 0.5},
    ]
)

# for urls: nv.volumes[1].set_colormap_label_from_url("./images/inia19-NeuroMaps.json")
with open(DATA_FOLDER / "inia19-NeuroMaps.json") as f:
    cmap = json.load(f)

nv.volumes[1].set_colormap_label(cmap)

nv.volumes[1].opacity = 0.03
nv.set_atlas_outline(0.01)

## UI
# Slider for opacity
opacity_slider = widgets.IntSlider(
    min=1,
    max=255,
    value=8,
    description="Opacity",
    continuous_update=True,
    readout=False,
)


location_label = widgets.HTML(" ")


outline_options = ["None", "Gap", "Opaque", "Black"]
outline_dropdown = widgets.Dropdown(
    options=outline_options,
    value="Gap",
    description="Atlas outline",
)

render_options = ["Slices", "Matte", "Low", "Medium", "High"]
render_dropdown = widgets.Dropdown(
    options=render_options,
    value="Matte",
    description="Render mode",
    style={"description_width": "initial"},
)

## Define callbacks


def on_opacity_change(change):
    """Update the opacity of the atlas volume."""
    nv.volumes[1].opacity = change["new"] / 255


def on_outline_change(change):
    """Set atlas outline style."""
    value_name = change["new"]

    # Default borderValue for "No border"
    borderValue = 0.0
    if value_name == "Gap":
        borderValue = 0.01
    elif value_name == "Opaque":
        borderValue = 1
    elif value_name == "Black":
        borderValue = -1.0
    # else "None" → 0.0
    nv.set_atlas_outline(borderValue)


def on_render_change(change):
    """Set render mode."""
    value_name = change["new"]
    # Default borderValue for "matte"
    renderValue = 0.0
    if value_name == "Slices":
        renderValue = -1.0
    elif value_name == "Low":
        renderValue = 0.3
    elif value_name == "Medium":
        renderValue = 0.6
    elif value_name == "High":
        renderValue = 1.0
    # else "Matte" → 0.0
    nv.set_volume_render_illumination(renderValue)
    nv.update_gl_volume()


def handle_location_change(location):
    """Update the location label with current coordinates."""
    region = int(location["values"][1]["value"])
    if region == nv.opts.atlas_active_index:
        return
    nv.set_atlas_active_index(region)
    location_label.value = location["string"]


## Setup observers

opacity_slider.observe(on_opacity_change, names="value")
nv.on_location_change(handle_location_change)
on_opacity_change({"new": opacity_slider.value})
outline_dropdown.observe(on_outline_change, names="value")
render_dropdown.observe(on_render_change, names="value")

## Display All

controls = widgets.HBox([opacity_slider, outline_dropdown, render_dropdown])

display(
    widgets.VBox(
        [
            controls,
            nv,
            location_label,
        ]
    )
)